/************************************************************************/
/* Bluteooth Test           The.Berlin.Factor                 Juni 2003 */
/************************************************************************/

#include <E32Math.h>
#include "NmeaParser.h"



void CNmeaParser::SetData( TDesC8 & aNmeaMessage ) {
	iMessage = &aNmeaMessage;
	iParsePosition = 0;
}



void CNmeaParser::GetNextTokenIntoL( TDes8 & aBuffer ) {

	if ( iMessage == NULL )
		User::Leave( KErrNotReady );

	if ( iParsePosition >= iMessage->Length( ) )
		User::Leave( KErrNotFound );

	TUint8 nextChar;
	while ( iParsePosition < iMessage->Length( ) ) {
		nextChar = ( *iMessage )[ iParsePosition++ ];
		if ( nextChar == ',' )
			break;
		aBuffer.Append( nextChar );
	}

}



void CNmeaParser::SkipNextTokenL( ) {

	if ( iMessage == NULL )
		User::Leave( KErrNotReady );

	if ( iParsePosition >= iMessage->Length( ) )
		User::Leave( KErrNotFound );

	TUint8 nextChar;
	while ( iParsePosition < iMessage->Length( ) ) {
		nextChar = ( *iMessage )[ iParsePosition++ ];
		if ( nextChar == ',' )
			break;
	}

}



TInt CNmeaParser::GetNextTokensAsLatitudeL( TReal & latitude ) {

	TReal angle;

	TBuf8< 15 > angleString;
	GetNextTokenIntoL( angleString );

    if (angleString.Length()==0){
    	return KErrGeneral  ;
    }

	TBuf8< 5 > northSouth;
	GetNextTokenIntoL( northSouth );
    if (northSouth.Length()==0){
        return KErrGeneral  ;
    }

	TLex8 latLexer( angleString );
	TInt error = latLexer.Val( angle, '.' );

	if ( error != KErrNone )
		User::Leave( error );

	TInt32 degrees;
	Math::Int( degrees, angle / 100.0 );

	TInt32 minutes;
	Math::Int( minutes, angle - degrees * 100 );

	TReal decimal;
	Math::Frac( decimal, angle );

	latitude = degrees + ( minutes + decimal ) / 60.0;

	if ( northSouth[ 0 ] == 'S' )
		latitude = -latitude;

    return 0;

}



TInt CNmeaParser::GetNextTokensAsLongitudeL(TReal & longitude) {

	TReal angle;

	TBuf8< 15 > angleString;
	GetNextTokenIntoL( angleString );
    if (angleString.Length()==0){
        return KErrGeneral ;
    }

	TBuf8< 5 > northSouth;
	GetNextTokenIntoL( northSouth );

    if (northSouth.Length()==0){
    	return KErrGeneral ;
    }

	TLex8 latLexer( angleString );
	TInt error = latLexer.Val( angle, '.' );

	if ( error != KErrNone )
		User::Leave( error );

	TInt32 degrees;
	Math::Int( degrees, angle / 100.0 );

	TInt32 minutes;
	Math::Int( minutes, angle - degrees * 100 );

	TReal decimal;
	Math::Frac( decimal, angle );

	longitude = degrees + ( minutes + decimal ) / 60.0;

	if ( northSouth[ 0 ] == 'W' )
		longitude = -longitude;

	return( 0 );

}



TInt CNmeaParser::GetNextTokenAsIntL( ) {

	TInt result = 0;

	TBuf8< 10 > intString;
	GetNextTokenIntoL( intString );

	TLex8 lexer( intString );
	User::LeaveIfError( lexer.Val( result ) );
	return( result );

}



TReal CNmeaParser::GetNextTokenAsRealL( ) {

	TReal result = 0;

	TBuf8< 10 > realString;
       // iLog.Write(_L("Voy a sacar la hora"));
	GetNextTokenIntoL( realString );

        //iLog.Write(_L("La convierto a numerito"));
	TLex8 lexer( realString );
	User::LeaveIfError( lexer.Val( result ) );

        //iLog.Write(_L("Ya la tengo"));
	return( result );

}



void CNmeaParser::ClearData( ) {

	iMessage = NULL;
	iParsePosition = 0;

}
